{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# <center> __Deep Learning__ <br/> <br/><br/>\n",
    "# <center> учим машину распознaвать текст"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## <center> Атабек Дулат - Machine Learning Engineer в Kolesa Group\n",
    "<br/><br/>\n",
    "### <center> Опыт работы: работал в Нацбанке РК и BTSD\n",
    "<br/><br/>\n",
    "### <center> Гитхаб с презентацией и кодом обучения сетки : \n",
    "###    <center> https://github.com/carnotaur/crnn-tutorial"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "# <center> __План:__\n",
    "<br/><br/>\n",
    "##  1. Быстрый обзор методов распознавания\n",
    "##  2. __CRNN__ - What it is?\n",
    "## 3. Попытка в 'простое' обьяснение __CNN__\n",
    "## 4. Попытка(но хуже) в обьяснение __RNN__\n",
    "## 5. Back to the CRNN\n",
    "## 6. Распознаем капчу и показываю модель"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### <center> Задача - Optical Character Recognition a.k.a __OCR__\n",
    "<center> <img src=\"imgs/ocr_working.gif\" width=1800>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Распознавание текста можно разделить на 2 этапа: \n",
    "<br/><br/>\n",
    "###  <center> - Определение местоположение текста (Text Detection)\n",
    "###  <center> - Распознавание текста (OCR)\n",
    "<br/><br/>\n",
    "<center> <img src=\"imgs/ocr-types.png\" width=1600>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center>  Как было раньше:\n",
    "<br/><br/>\n",
    "<center> <img src=\"imgs/oldway.png\" width=1000>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# <center> Эра __\"Глубокого Обучения\"__ поменяло все"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Зоопарк recongition моделей\n",
    "<br/><br/><br/>\n",
    "<center> <img src=\"imgs/recongition_types.png\" width=2600>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Convolutional Recurrent Neural Network (CRNN)\n",
    "<br/><br/><br/>\n",
    "<center> <img src=\"imgs/crnn-archit.png\" width=1000>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# <center> __Convolutions__ a.k.a Свертки - Как они работают? \n",
    "<br/><br/><br/>\n",
    "<center> <img src=\"imgs/img_pixels.png\"  width=1500>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Принцип работы сверток \n",
    "<br/><br/><br/>\n",
    "<center> <img src=\"imgs/kernels.png\" width=1500>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Принцип работы сверток \n",
    "<br/><br/><br/>\n",
    "\n",
    "<center> <img src=\"imgs/3D_Convolution_Animation.gif\" height=1200 width=1200>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Свертки способны выучить очень сложные признаки <br/><br/>\n",
    "\n",
    "<center> <img src=\"imgs/cnn-feaures.png\" width=1800>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# <center> __Recurrent Neural Network (RNN)__  - Вторая часть уравнения"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center>  __RNN__ - отлично подходят для работы с sequences\n",
    "<center> <img src=\"imgs/rnn-works.png\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Как работает один блок RNN\n",
    "<br/><br/>\n",
    "<center> <img src=\"imgs/one_block.png\"  width=1500>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Каждый блок имеет общую матрицу весов $W$ \n",
    "<br/><br/><br/><br/>\n",
    "\n",
    "<center> <img src='imgs/several blocks.png' width=1500>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# <center> Вернемся к __CRNN__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Convolutional Recurrent Neural Network (CRNN) \n",
    "<br/><br/>\n",
    "<center> <img src=\"imgs/crnn-archit.png\" width=900>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Переход от image features к sequences\n",
    "<center> <img src=\"imgs/features-seq.png\" width=1500>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> Зачем использовать __RNN__ ? <br/><br/>\n",
    "\n",
    "## 1. Возможность комбинировать информацию с нескольких receptive fields для сохранения __контекста__\n",
    "## 2. По сравнению с прошлыми решениями RNN могут обучаться с помощью __back-propagation__ и могут обучаться сразу СNN и RNN\n",
    "## 3. RNN работает на последовательнастях c __различной__ длиной"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> __LSTM__ вместо обычного __RNN__\n",
    "<br/><br/><br/><br/>\n",
    "<center> <img src='imgs/lstm.png' width=1800>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> __Connectionist Temporal Classification (CTC)__ <br/><br/>\n",
    "\n",
    "  ### <center> $P(L / Y)$, где\n",
    "  ### <center> $L$ - label sequence, предсказываемый текст\n",
    "### <center> $Y$ per-frame предсказания модели"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## <center> __СTC__ позволяет тренировать сеть используя __Negative Log Likeilihood Loss (NLLL)__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "import string\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torchvision.models import resnet18\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from PIL import Image\n",
    "from layers import blockCNN, blockRNN\n",
    "from utils.utils import strLabelConverter, decode_prediction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "class CRNN(nn.Module):\n",
    "    def __init__(self, hidden_size: int, \n",
    "                 vocab_size: int, \n",
    "                 bidirectional: bool = True, \n",
    "                 dropout: float = 0.5):\n",
    "        super(CRNN, self).__init__()\n",
    "        # layers\n",
    "        resnet = resnet18(pretrained=True)\n",
    "        modules = list(resnet.children())[:-3]\n",
    "        self.resnet = nn.Sequential(*modules)\n",
    "        self.cn6 = blockCNN(256, 256, kernel_size=3, padding=1)\n",
    "        # RNN + Linear\n",
    "        self.linear1 = nn.Linear(1024, 256)\n",
    "        self.gru1 = blockRNN(256, hidden_size, hidden_size, dropout=dropout, \n",
    "                             bidirectional=bidirectional)\n",
    "        self.gru2 = blockRNN(hidden_size, hidden_size, vocab_size, dropout=dropout,\n",
    "                             bidirectional=bidirectional)\n",
    "        self.linear2 = nn.Linear(hidden_size * 2, vocab_size)\n",
    "        \n",
    "    def forward(self, batch: torch.Tensor): \n",
    "        batch_size = batch.size(0)\n",
    "        # convolutions\n",
    "        batch = self.resnet(batch)\n",
    "        batch = self.cn6(batch, use_relu=True, use_bn=True)\n",
    "        # make sequences of image features\n",
    "        batch = batch.permute(0, 3, 1, 2)\n",
    "        n_channels = batch.size(1)\n",
    "        batch = batch.view(batch_size, n_channels, -1)\n",
    "        batch = self.linear1(batch)\n",
    "        # rnn layers\n",
    "        batch = self.gru1(batch, add_output=True)\n",
    "        batch = self.gru2(batch)\n",
    "        # output\n",
    "        batch = self.linear2(batch)\n",
    "        batch = batch.permute(1, 0, 2)\n",
    "        return batch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "abcdefghijklmnopqrstuvwxyz0123456789\n"
     ]
    }
   ],
   "source": [
    "alphabet = string.ascii_lowercase + string.digits #все возможные буквы в капче\n",
    "label_converter = strLabelConverter(alphabet) #энкодер надписей\n",
    "print(alphabet)\n",
    "hidden_size = 256\n",
    "vocab_size = len(alphabet) + 1 # один дополнительный слот для 'blank' знака\n",
    "bidirectional = True\n",
    "PATH = 'models/crnn.pt'\n",
    "\n",
    "crnn = CRNN(hidden_size=hidden_size, vocab_size=vocab_size, bidirectional=bidirectional)\n",
    "crnn.load_state_dict(torch.load(PATH))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "CRNN(\n",
       "  (resnet): Sequential(\n",
       "    (0): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n",
       "    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (2): ReLU(inplace)\n",
       "    (3): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n",
       "    (4): Sequential(\n",
       "      (0): BasicBlock(\n",
       "        (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu): ReLU(inplace)\n",
       "        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      )\n",
       "      (1): BasicBlock(\n",
       "        (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu): ReLU(inplace)\n",
       "        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      )\n",
       "    )\n",
       "    (5): Sequential(\n",
       "      (0): BasicBlock(\n",
       "        (conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
       "        (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (downsample): Sequential(\n",
       "          (0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)\n",
       "          (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (1): BasicBlock(\n",
       "        (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      )\n",
       "    )\n",
       "    (6): Sequential(\n",
       "      (0): BasicBlock(\n",
       "        (conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
       "        (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu): ReLU(inplace)\n",
       "        (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (downsample): Sequential(\n",
       "          (0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)\n",
       "          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (1): BasicBlock(\n",
       "        (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu): ReLU(inplace)\n",
       "        (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "        (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      )\n",
       "    )\n",
       "  )\n",
       "  (cn6): blockCNN(\n",
       "    (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "  )\n",
       "  (linear1): Linear(in_features=1024, out_features=256, bias=True)\n",
       "  (gru1): blockRNN(\n",
       "    (gru): GRU(256, 256, bidirectional=True)\n",
       "  )\n",
       "  (gru2): blockRNN(\n",
       "    (gru): GRU(256, 256, bidirectional=True)\n",
       "  )\n",
       "  (linear2): Linear(in_features=512, out_features=37, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "crnn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "batch size : 1\n",
      "num of channels : 3\n",
      "height : 50\n",
      "width : 200\n"
     ]
    }
   ],
   "source": [
    "SAMPLE_PATH = 'data/sample/2b827.png'\n",
    "# load image \n",
    "img_array = np.asarray(Image.open(SAMPLE_PATH).convert('RGB'))\n",
    "# convert to tensor\n",
    "img_tensor = torch.from_numpy(img_array / 255.)\n",
    "img_tensor = img_tensor.permute(2, 0, 1).unsqueeze(0).to(torch.float32)\n",
    "\n",
    "descr_list = ['batch size', 'num of channels', 'height', 'width']\n",
    "for descr, s in zip(descr_list, img_tensor.size()):\n",
    "    print('%s : %s' % (descr, s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "logits = crnn(img_tensor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "max seq len : 13\n",
      "batch size : 1\n",
      "vocab size : 37\n"
     ]
    }
   ],
   "source": [
    "descr_list = ['max seq len', 'batch size', 'vocab size']\n",
    "for descr, s in zip(descr_list, logits.size()):\n",
    "    print('%s : %s' % (descr, s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x1440 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "pred = decode_prediction(logits, label_converter)\n",
    "plt.figure(figsize=(15, 20))\n",
    "plt.title(pred, fontsize=40)\n",
    "plt.imshow(img_array)\n",
    "plt.axis('off');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    ".# <center> -  Гитхаб с презентацией и кодом обучения сетки :  \n",
    "# <center> - https://github.com/carnotaur/crnn-tutorial  \n",
    "# <center>\n",
    "# <center> - Ссылка на мой linkedin:\n",
    "# <center> - www.linkedin.com/in/dulatatabek\n",
    "# <center>\n",
    "# <center> - Вопросы по презентации можете посылать:\n",
    "# <center> - predator2013@protonmail.com\n",
    "    "
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
